package com.binguo.wxapi.wxpay;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.DnsResolver;
import org.apache.http.conn.HttpConnectionFactory;
import org.apache.http.conn.ManagedHttpClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SystemDefaultDnsResolver;
import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
import org.apache.http.impl.io.DefaultHttpResponseParserFactory;
import org.apache.http.ssl.SSLContexts;
import org.springframework.core.io.DefaultResourceLoader;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

public class HttpConnectionManager {

    static PoolingHttpClientConnectionManager cm = null;

    static CloseableHttpClient httpClient = null;

//    @PostConstruct
    public static void init() throws Exception {
        if (httpClient != null) {
            return;
        }
        System.out.println("------------------HttpConnectionManager----init----");
        LayeredConnectionSocketFactory sslsf = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            org.springframework.core.io.Resource resource = new DefaultResourceLoader().getResource("classpath:/cert/apiclient_cert.p12");//P12文件目录

            keyStore.load(resource.getInputStream(), new WXServerPayConfig().getMchID().toCharArray());//这里写密码


            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, new WXServerPayConfig().getMchID().toCharArray())//这里也是写密码的
                    .build();
            sslsf = new SSLConnectionSocketFactory(sslcontext);
//            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }


        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("https", sslsf)
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .build();



        HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection>
                connectionFactory = new ManagedHttpClientConnectionFactory(DefaultHttpRequestWriterFactory.INSTANCE,
                DefaultHttpResponseParserFactory.INSTANCE);

        DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;

        cm =new PoolingHttpClientConnectionManager(socketFactoryRegistry, connectionFactory, dnsResolver);
        cm.setMaxTotal(4000);
        cm.setDefaultMaxPerRoute(2000);

        SocketConfig defaultSocketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
        cm.setDefaultSocketConfig(defaultSocketConfig);

        cm.setValidateAfterInactivity(15 * 10000);

        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setConnectTimeout(15 * 10000)
                .setSocketTimeout(15 * 10000)
                .setConnectionRequestTimeout(150000).build();

        httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .setConnectionManagerShared(false)
                .evictIdleConnections(60, TimeUnit.MILLISECONDS)
                .evictExpiredConnections()
                .setDefaultRequestConfig(defaultRequestConfig)
                .setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE)
                .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(5, true))
                .build();


        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public static CloseableHttpClient getHttpClient() {
        if (httpClient == null) {
            try {
                init();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return httpClient;
    }



}